from django.utils import translation
from django.utils.functional import cached_property
from rest_framework import serializers
from modeltranslation.translator import translator
from modeltranslation import settings

from .settings import LANGUAGE_PARAM, LOCALE_CONTEXT

class TranslatedModelSerializer(serializers.ModelSerializer):
    @property
    def translation_options(self):
        return translator.get_options_for_model(self.Meta.model)

    @cached_property
    def translation_fields_map(self):
        result = dict()

        fields = self.get_fields()

        trans_fields = self.translation_options.fields

        for key in fields:
            field = fields[key]

            source = field.source or key

            if source in trans_fields:
                result[key] = source

        return result

    def to_internal_value(self, data):
        trans_fields_map = self.translation_fields_map

        result = data.copy()

        for key in data:
            if key not in trans_fields_map:
                continue

            value = data[key]

            text = ''

            for language in settings.AVAILABLE_LANGUAGES:
                if language in value or not self.instance:
                    text = value.get(language, '')

                    result[f'{key}_{language}'] = text

            result[key] = value.get(settings.DEFAULT_LANGUAGE, text)

        return super().to_internal_value(result)

    def to_representation(self, instance):
        repr = super().to_representation(instance)

        trans_fields_map = self.translation_fields_map

        trans_fields = self.translation_options.fields
        
        context = self.context

        locale = context.get(LOCALE_CONTEXT)
        
        request = context.get('request')

        if not locale and request:
            locale = request.GET.get(LANGUAGE_PARAM)

        for key in repr:
            if key not in trans_fields_map:
                continue

            source = trans_fields_map[key]
            
            fields = trans_fields[source]

            if locale:
                translation.activate(locale)

                repr[key] = getattr(instance, source)
                
                continue

            repr[key] = dict()

            for field in fields:
                value = field.value_to_string(instance)

                repr[key][field.language] = value

        return repr

